#include "stdafx.h"

#include "common.h"

#include "..\..\includes\mfciterators.h"


using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTests
{		
   TEST_CLASS(Array_UnitTest)
   {      
   public:

      TEST_METHOD(Test_CTypedPtrArray_CObArray)
      {
         CTypedPtrArray<CObArray, CFooObject*> obarr;

         for(auto v : g_sample)
            obarr.Add(new CFooObject(v));

         auto i = 0;
         for(auto o : obarr)
         {
            Assert::AreEqual(o->value, g_sample[i++]);
         }

         TraceTest(obarr, L"%p");
         TraceTestConst(obarr, L"%p");

         for(auto& o : obarr)
         {
            o->value *= 2;
         }

         i = 0;
         for(auto const & o : obarr)
         {
            Assert::AreEqual(o->value, g_sample[i++] * 2);
         }

         for(auto o : obarr)
            delete o;
      }

      TEST_METHOD(Test_CTypedPtrArray_CPtrArray)
      {
         CTypedPtrArray<CPtrArray, CBar*> ptrarr;
         for(auto v : g_sample)
            ptrarr.Add(new CBar(v));

         auto i = 0;
         for(auto o : ptrarr)
         {
            Assert::AreEqual(o->value, g_sample[i++]);
         }

         TraceTest(ptrarr, L"%p");
         TraceTestConst(ptrarr, L"%p");

         for(auto& o : ptrarr)
         {
            o->value *= 2;
         }

         i = 0;
         for(auto const & o : ptrarr)
         {
            Assert::AreEqual(o->value, g_sample[i++] * 2);
         }

         for(auto o : ptrarr)
            delete o;
      }

      TEST_METHOD(Test_CObArray)
      {
         CObArray obarr;
         for(auto v : g_sample)
            obarr.Add(new CFooObject(v));

         auto i = 0;
         for(auto o : obarr)
         {
            Assert::AreEqual((static_cast<CFooObject*>(o))->value, g_sample[i++]);
         }

         TraceTest(obarr, L"%p");
         TraceTestConst(obarr, L"%p");

         for(auto& o : obarr)
         {
            (static_cast<CFooObject*>(o))->value *= 2;
         }

         i = 0;
         for(auto const & o : obarr)
         {
            Assert::AreEqual((static_cast<CFooObject*>(o))->value, g_sample[i++] * 2);
         }

         for(auto o : obarr)
            delete o;
      }
      
      TEST_METHOD(Test_CByteArray)
      {
         CByteArray barr;

         for(auto v : g_sample)
            barr.Add((BYTE)v);

         TestNumeric<CByteArray, BYTE>(barr, g_sample);
         TestNumericConst<CByteArray, BYTE>(barr, g_sample);

         for(auto& v : barr)
            v *= 2;

         TestNumeric<CByteArray, BYTE>(barr, g_sample2);
         TestNumericConst<CByteArray, BYTE>(barr, g_sample2);
      }

      TEST_METHOD(Test_CDWordArray)
      {
         CDWordArray dwarr;

         for(auto v : g_sample)
            dwarr.Add((DWORD)v);

         TestNumeric<CDWordArray, DWORD>(dwarr, g_sample);
         TestNumericConst<CDWordArray, DWORD>(dwarr, g_sample);

         for(auto& v : dwarr)
            v *= 2;

         TestNumeric<CDWordArray, DWORD>(dwarr, g_sample2);
         TestNumericConst<CDWordArray, DWORD>(dwarr, g_sample2);
      }

      TEST_METHOD(Test_CPtrArray)
      {
         CPtrArray ptrarr;
         for(auto v : g_sample)
            ptrarr.Add(new CBar(v));

         auto i = 0;
         for(auto o : ptrarr)
         {
            Assert::AreEqual((static_cast<CBar*>(o))->value, g_sample[i++]);
         }

         TraceTest(ptrarr, L"%p");
         TraceTestConst(ptrarr, L"%p");

         for(auto& o : ptrarr)
         {
            (static_cast<CBar*>(o))->value *= 2;
         }

         i = 0;
         for(auto const & o : ptrarr)
         {
            Assert::AreEqual((static_cast<CBar*>(o))->value, g_sample[i++] * 2);
         }

         for(auto o : ptrarr)
            delete o;
      }

      TEST_METHOD(Test_CStringArray)
      {
         CStringArray strarr;

         for(auto const & v : g_sample_str)
            strarr.Add(v);

         TraceTest(strarr, L"%s");
         TraceTestConst(strarr, L"%s");

         auto i = 0;
         for(auto v : strarr)
         {
            Assert::AreEqual(v, g_sample_str[i++]);
         }

         for(auto& v : strarr)
            v.MakeUpper();

         i = 0;
         for(auto v : strarr)
         {
            Assert::AreEqual(v, g_sample2_str[i++]);
         }
      }

      TEST_METHOD(Test_CWordArray)
      {
         CWordArray warr;

         for(auto v : g_sample)
            warr.Add((WORD)v);

         TestNumeric<CWordArray, WORD>(warr, g_sample);
         TestNumericConst<CWordArray, WORD>(warr, g_sample);

         for(auto& v : warr)
            v *= 2;

         TestNumeric<CWordArray, WORD>(warr, g_sample2);
         TestNumericConst<CWordArray, WORD>(warr, g_sample2);
      }

      TEST_METHOD(Test_CUIntArray)
      {
         CUIntArray uiarr;

         for(auto v : g_sample)
            uiarr.Add((UINT)v);

         TestNumeric<CUIntArray, UINT>(uiarr, g_sample);
         TestNumericConst<CUIntArray, UINT>(uiarr, g_sample);

         for(auto& v : uiarr)
            v *= 2;

         TestNumeric<CUIntArray, UINT>(uiarr, g_sample2);
         TestNumericConst<CUIntArray, UINT>(uiarr, g_sample2);
      }

      TEST_METHOD(Test_CArray_int)
      {
         CArray<int> arr;

         for(auto v : g_sample)
            arr.Add(v);

         TestNumeric<CArray<int>, int>(arr, g_sample);
         TestNumericConst<CArray<int>, int>(arr, g_sample);

         for(auto& v : arr)
            v *= 2;

         TestNumeric<CArray<int>, int>(arr, g_sample2);
         TestNumericConst<CArray<int>, int>(arr, g_sample2);
      }

      TEST_METHOD(Test_CArray_CString)
      {
         CArray<CString> strarr;

         for(auto const & v : g_sample_str)
            strarr.Add(v);

         TraceTest(strarr, L"%s");
         TraceTestConst(strarr, L"%s");

         auto i = 0;
         for(auto v : strarr)
         {
            Assert::AreEqual(v, g_sample_str[i++]);
         }

         for(auto& v : strarr)
            v.MakeUpper();

         i = 0;
         for(auto v : strarr)
         {
            Assert::AreEqual(v, g_sample2_str[i++]);
         }
      }
   };
}